package main

import (
	"database/sql"
	"fmt"

	_ "github.com/go-sql-driver/mysql" //init()
)

var db *sql.DB
var dsn string = "root:root333@tcp(127.0.0.1:3306)/go_sql_test"

// 初始化数据库
func initDb() (err error) {
	// 连接数据库
	db, err = sql.Open("mysql", dsn)
	if err != nil {
		return
	}
	err = db.Ping()
	if err != nil {
		return
	}
	// 设置数据库连接池最大数目，默认为0，即不限制，超过连接数目，会产生阻塞
	db.SetMaxOpenConns(10)
	// 设置连接池中最大闲置连接数目（请求数据量较小时，会关闭部分连接池）
	db.SetMaxIdleConns(5)
	return nil
}

func transactionDemo() {
	// 1.开启事务
	tx, err := db.Begin()
	if err != nil {
		fmt.Printf("begin failed, err: %v\n", err)
		return
	}
	// 2. 执行sql语句
	sqlStr1 := "UPDATE user set age=age-10 where id=1;"
	sqlStr2 := "UPDATE user set age=age+10 where id=2;"
	// 执行sql1
	ret1, err := tx.Exec(sqlStr1)
	if err != nil {
		// 回滚
		tx.Rollback()
		fmt.Println("执行sql2失败了，回滚")
		return
	}
	// 执行sql2
	ret2, err := tx.Exec(sqlStr2)
	if err != nil {
		// 回滚
		tx.Rollback()
		fmt.Println("执行sql2失败了，回滚")
		return
	}
	// 提交事务
	err = tx.Commit()
	if err != nil {
		// 回滚
		tx.Rollback()
		fmt.Println("提交失败，回滚")
		return
	}
	fmt.Println("事务执行成功！！！", ret1, ret2)
}

func main() {
	err := initDb()
	if err != nil {
		fmt.Printf("init DB failed, err: %v\n", err)
		return
	}
	fmt.Println("数据库连接成功")

	transactionDemo()
}
